<template>
  <el-select v-model="selectValues"
             :max-collapse-tags="maxCollapseTags"
             :placeholder="placeholder"
             clearable
             collapse-tags
             multiple>
    <template v-if="showCheckAll && options.length > 0" #header>
      <div class="select-control">
        <div class="select-search">
          <el-input ref="filterRef" v-model="filterText" :prefix-icon="Search" clearable placeholder="输入关键字进行过滤"/>
        </div>
        <div class="select-control__btns">
          <el-button size="small" text type="primary" @click="handleCheck(true)">全选</el-button>
          <el-button size="small" text type="primary" @click="handleCheck(false)">反选</el-button>
        </div>
      </div>
    </template>
    <el-checkbox-group v-model="selectValues">
      <el-option v-for="item in optionsList" :key="item.value" :label="item.label" :value="item.value">
        <el-checkbox :value="item.value" style="pointer-events: none">
          {{ item.label }}
        </el-checkbox>
      </el-option>
    </el-checkbox-group>
  </el-select>
</template>

<script lang="ts" setup>
import { computed, PropType, ref } from 'vue'
import { DictItem } from '@/utils/global-dict.ts';
import { Search } from '@element-plus/icons-vue';

defineOptions({name: 'MultipleSelect'})

const props = defineProps({
  modelValue: {
    type: Array as PropType<Number[]>,
    require: false,
    default: () => [],
  },
  placeholder: {
    type: String,
    default: '请选择'
  },
  options: {
    type: Array as PropType<DictItem[]>,
    default: () => [],
  },
  showCheckAll: {
    type: Boolean,
    default: true
  },
  maxCollapseTags: {
    type: Number,
    default: 1
  }
});

const emit = defineEmits(['update:modelValue']);
const filterText = ref('');
const selectValues = computed({
  get: () => props.modelValue,
  set: (val) => {
    emit('update:modelValue', val);
  },
});

const optionsList = computed(() => {
  let list: DictItem[] = props.options;
  if (filterText.value && filterText.value != '') {
    list = props.options.filter((item) => item.label.includes(filterText.value));
  }
  return list;
})

/** 处理全选/不选事件 */
const handleCheck = (selectAll: boolean) => {
  if (selectAll) {
    selectValues.value = props.options.map((item) => item.value as number)
  } else {
    selectValues.value = []
  }
}
</script>

<style lang="scss" scoped>
.select-search {
  margin-bottom: 6px;
}

.el-select-dropdown__header {
  padding: 10px 10px 5px 10px;
}

:deep(.el-select-dropdown__item.is-selected::after) {
  display: none !important;
}
</style>
